﻿using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Threading;
using System.Timers;
using DGM.Objects.General;
using DGM.Objects.Msmq;
using DGM.Objects.SocialMedia;
using DGM.Util.Helpers.Json;
using DGM.Util.Helpers.Msmq;
using XSockets.Core.Globals;
using XSockets.Core.XSocket;
using XSockets.Core.XSocket.Event.Arguments;
using XSockets.Core.XSocket.Event.Attributes;
using XSockets.Core.XSocket.Helpers;
using XSockets.Core.XSocket.Interface;

namespace XSocketHandler
{
    [Export(typeof(IXBaseSocket))]
    [XBaseSocketMetadata("SocialAnalyzerWebSocket", Constants.GenericTextBufferSize)]
    public class SocialAnalyzerWebSocket : XBaseSocket
    {
        ConcurrentDictionary<string, ConcurrentQueue<string>> _cachedRealtimeData = new ConcurrentDictionary<string, ConcurrentQueue<string>>();

        List<string> _cached10SecData = new List<string>();
        ConcurrentDictionary<string, ConcurrentQueue<ClassifiedTweet>> _holder10SecData = new ConcurrentDictionary<string, ConcurrentQueue<ClassifiedTweet>>();
        System.Timers.Timer _timer10Secs;

        ConcurrentDictionary<string, ConcurrentQueue<ClassifiedTweet>> _holder60SecData = new ConcurrentDictionary<string, ConcurrentQueue<ClassifiedTweet>>();
        System.Timers.Timer _timer60Secs;

        public SocialAnalyzerWebSocket()
        {
            OnClientConnect += OnOnClientConnect;

            Thread a = new Thread(Test);
            a.Start();
        }

        private void QueueCallback(ResultObject<ClassifiedTweet> obj)
        {
            var data = obj.Data;

            var queue10Secs = _holder10SecData.GetOrAdd(data.CategoryGroup,
                                                        delegate(string s)
                                                            { return new ConcurrentQueue<ClassifiedTweet>(); });

            var realTimeListCache = _cachedRealtimeData.GetOrAdd(data.CategoryGroup,
                                                                 delegate(string s) { return new ConcurrentQueue<string>(); });

            queue10Secs.Enqueue(data);

            string jsonData = JsonHelper.GetJsonFromWellKnownOjbect(data);

            realTimeListCache.Enqueue(jsonData);

            OnTweetMessage(jsonData);
        }

        private void Test()
        {
            MsmqManager.ListenToQueueAsync<ClassifiedTweet>(QueueType.Private, "ClassifiedTwitterQueue", QueueCallback, "FormatName:DIRECT=OS:24cptl-dmostert");

            _timer10Secs = new System.Timers.Timer(10000);
            _timer10Secs.Elapsed += Callback10Secs;
            _timer10Secs.Enabled = true;
        }

        private void Callback10Secs(object sender, ElapsedEventArgs e)
        {
	        double totalPos = 0;
	        double totalNeg = 0;
	        double totalKlout = 0;

            foreach (var key in _holder10SecData.Keys)
            {
                ConcurrentQueue<ClassifiedTweet> queue;

                if (_holder10SecData.TryGetValue(key, out queue))
                {
                    int countHolder = queue.Count;
                    for (int i = 0; i <= countHolder; i++)
                    {
                        ClassifiedTweet tweet;
                        if (queue.TryDequeue(out tweet))
                        {
													totalPos += tweet.PositiveSentiment * tweet.Klout;
													totalNeg += tweet.NegativeSentiment * tweet.Klout;
	                        totalKlout += tweet.Klout;
                        }
                    }

                    ClassifiedTweet tweetObject = new ClassifiedTweet();
										if (totalKlout != 0.0)
											tweetObject.CalculatedMasterValue = (totalPos - totalNeg) / totalKlout;
										else
											tweetObject.CalculatedMasterValue = 0.0;
                    tweetObject.CategoryGroup = TickerExtensions.TickerDescription(key);

                    string jsonData = JsonHelper.GetJsonFromWellKnownOjbect(tweetObject);

                    On10SecMessage(jsonData);
                }
            }
        }

        private void OnOnClientConnect(object sender, OnClientConnectArgs onClientConnectArgs)
        {
            foreach (var key in _cachedRealtimeData.Keys)
            {
                ConcurrentQueue<string> list;
                if(_cachedRealtimeData.TryGetValue(key, out list))
                {
                    foreach (var data in list)
                    {
                        OnTweetMessage(data);
                    }
                }
                
            }
        }

        [HandlerEvent("OnTweetMessage")]
        public void OnTweetMessage(string data)
        {
            this.SendTo(p => p.XSocket.Socket.Connected, data, "OnTweetMessage");
        }

        [HandlerEvent("On10SecMessage")]
        public void On10SecMessage(string data)
        {
            this.SendTo(p => p.XSocket.Socket.Connected, data, "On10SecMessage");
        }

        /*var sec10Values = [0];
        var sec30Values = [0];
        var sec60Values = [0];*/

        #region Overrides of XBaseSocket

        public override IXBaseSocket NewInstance()
        {
            return new SocialAnalyzerWebSocket();
        }

        #endregion
    }
}
